class RouteRecurrenceRule < ActiveRecord::Base

  Days = [:su,:m,:t,:w,:th,:f,:s]
  DayToI = Hash[Days.zip((0..6).to_a.map(&:to_s))]
  IToDay = DayToI.invert
  
  # ActiveRecord uses this
  def respond_to?(m, *args, &block)
	return true if DayToI.member? m or (DayToI.member? m.to_s[0...-1].to_sym and m.to_s.last == '=')
	super
  end
  
  # implements virtual fields .su through .s using the private methods
  # day and set_day
  def method_missing(m, *args, &block)
    return day(m) if DayToI.member? m
	d = m.to_s[0...-1].to_sym
    return set_day(d, args[0]) if DayToI.member? d and m.to_s.last == '='
	super
  end
  
  belongs_to :courier
  belongs_to :route

  validates_presence_of :days
  
  # TEST THIS
  def next_date
    today = Date.today
    gte = wdays.select {|x| x >= today.wday}
    if gte.size > 0
      today + (gte[0] - today.wday).days
    else
      today - today.wday + 7 + (wdays[0])
    end
  end

  # TEST THIS
  def next_dates(n)
    wdays = wdays()
    today = Date.today
    dates = []
    (0..(1 + n / wdays.size)).each {|offset|
      wdays.each {|wday|
        dates << (today - today.wday + wday + (offset * 7))
      }
    }
    dates.select {|x| x >= Date.today}[(0...n)]
  end
  
private
  def wdays
    days.split(',').map(&:to_i).sort
  end

  def set_day(day, bool)
    i = DayToI[day]
	self.days ||= ''
    if bool and bool != '0'
	  add_day_index(i)
	else
	  remove_day_index(i)
	end
  end
  
  def add_day_index(i)
    if self.days == ''
      self.days = i
    else
	  self.days += ',' + i
    end
  end
  
  def remove_day_index(i)
    self.days = self.days.split(',').select {|x|
	  x != i
	}.join ','
  end
  
  def day(day)
    i = DayToI[day]
    self.days ||= ''	
	self.days.split(',').member? i
  end  
end
